package service;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import util.UtilData;
import util.UtilMensagem;
import dao.GrupoProdutoDAO;
import dao.ItemCompraDAO;
import dao.ItemVendaDAO;
import dao.MarcaProdutoDAO;
import dao.ProdutoDAO;
import entity.GrupoProduto;
import entity.ItemCompra;
import entity.ItemVenda;
import entity.MarcaProduto;
import entity.Produto;
import enumeration.PeriodoEnum;
import exceptions.ParametroNuloException;
import exceptions.ServiceException;

/**
 * <p>
 * ClienteService
 * </p>
 * <p>
 * </p>
 * 
 * @author vinicius.silva
 * @version 1.0
 */
@Service
public class ProdutoServiceImpl extends BaseService implements ProdutoService,
		Serializable {

	private static final long serialVersionUID = 2892712219712130868L;

	@Autowired
	private MarcaProdutoDAO marcaProdutoDAO;
	@Autowired
	private GrupoProdutoDAO grupoProdutoDAO;

	@Autowired
	private ProdutoDAO produtoDAO;

	@Autowired
	private ItemCompraDAO itemCompraDAO;

	@Autowired
	private ItemVendaDAO itemVendaDAO;

	@Override
	@Transactional
	public void salvarProduto(Produto produto) {

		if (produto.getQtdaMaxima() < produto.getQtdaMinima()) {
			throw new ServiceException(UtilMensagem.getMensagem("MSG_0024"));
		}

		if (produto.getId() != null) {

			produto.setDataAlteracao(UtilData.getDataAtual());
			produto = produtoDAO.merge(produto);

		} else {
			produto.setDataInclusao(UtilData.getDataAtual());
			produtoDAO.salvar(produto);
		}
	}

	@Transactional
	public void desativar(Produto produto) {
		produto.setAtivo(false);
		salvarProduto(produto);
	}

	@Override
	@Transactional
	public void salvarGrupoProduto(GrupoProduto grupoProduto) {

		if (grupoProduto == null) {
			throw new ParametroNuloException(
					UtilMensagem.getMensagem("MSG_0037"));
		}

		if (grupoProduto.getId() == null) {
			grupoProduto.setDataInclusao(UtilData.getDataAtual());
			grupoProdutoDAO.salvar(grupoProduto);
		} else {
			grupoProduto.setDataAlteracao(UtilData.getDataAtual());
			grupoProdutoDAO.merge(grupoProduto);
		}
	}

	@Override
	@Transactional
	public void salvarMarcaProduto(MarcaProduto marcaProduto) {

		if (marcaProduto.getId() == null) {
			marcaProduto.setDataInclusao(UtilData.getDataAtual());
			marcaProdutoDAO.salvar(marcaProduto);
		} else {
			marcaProduto.setDataAlteracao(UtilData.getDataAtual());
			marcaProdutoDAO.merge(marcaProduto);
		}
	}

	@Override
	public List<Produto> listarTodosProdutos() {
		return produtoDAO.buscarTodos();
	}

	@Override
	public List<Produto> listarProdutosAtivos() {
		return produtoDAO.buscarAtivos();
	}

	@Override
	public List<MarcaProduto> listarTodasMarcasProduto() {
		return marcaProdutoDAO.buscarTodos();
	}

	@Override
	public List<GrupoProduto> listarTodosGruposProduto() {
		return grupoProdutoDAO.buscarTodos();
	}

	@Override
	public Produto criarNovoProduto() {
		Produto produto = new Produto();

		produto.setPeriodoMediaVenda(PeriodoEnum.SEMANAL);
		produto.setPeriodoProximoVencimento(PeriodoEnum.SEMANAL);

		produto.setQtdaMinima(0);
		produto.setQtdaMaxima(0);
		produto.setQtdaAtualEstoque(0);

		produto.setAtivo(true);

		return produto;
	}

	@Override
	public MarcaProduto criarNovoMarcaProduto() {
		MarcaProduto marcaProduto = new MarcaProduto();
		marcaProduto.setAtivo(true);
		return marcaProduto;
	}

	@Override
	public GrupoProduto criarNovoGrupoProduto() {
		GrupoProduto grupoProduto = new GrupoProduto();
		grupoProduto.setAtivo(true);
		return grupoProduto;
	}

	/**
	 * @see service.ProdutoService#buscarProdutoPorChave(java.lang.Long)
	 */
	@Override
	public Produto buscarProdutoPorChave(Long id) {

		Produto produto = produtoDAO.buscarPorChave(id);
		return produto;
	}

	@Override
	@Transactional
	public void remover(Produto produto) {
		produtoDAO.remover(produto);
	}

	@Override
	@Transactional
	public void removerGrupoProduto(GrupoProduto grupoProduto) {
		List<Produto> listaProduto = produtoDAO
				.buscarProdutosPorGrupo(grupoProduto);

		if (listaProduto != null && listaProduto.isEmpty() == false) {
			throw new ServiceException(UtilMensagem.getMensagem("MSG_0020"));
		}

		grupoProdutoDAO.remover(grupoProduto);
	}

	@Override
	@Transactional
	public void removerMarcaProduto(MarcaProduto marcaProduto) {
		List<Produto> listaProduto = produtoDAO
				.buscarProdutosPorMarca(marcaProduto);

		if (listaProduto != null && listaProduto.isEmpty() == false) {
			throw new ServiceException(UtilMensagem.getMensagem("MSG_0021"));
		}

		marcaProdutoDAO.remover(marcaProduto);
	}

	@Override
	public MarcaProduto buscarMarcaPorChave(Long id) {
		return marcaProdutoDAO.buscarPorChave(id);
	}

	@Override
	public GrupoProduto buscarGrupoPorChave(Long id) {
		return grupoProdutoDAO.buscarPorChave(id);
	}

	@Override
	public List<ItemCompra> listarComprasProdutoPorPeriodo(
			final Produto produto, final Date dataInicial, final Date dataFinal) {
		return itemCompraDAO.listarComprasProdutoPorPeriodo(produto,
				dataInicial, dataFinal);
	}

	@Override
	public List<ItemVenda> listarVendasProdutoPorPeriodo(final Produto produto,
			final Date dataInicial, final Date dataFinal) {
		return itemVendaDAO.listarVendasProdutoPorPeriodo(produto, dataInicial,
				dataFinal);
	}

	@Override
	public int buscarQuantidadeProdutosAtivos() {
		return produtoDAO.buscarQuantidadeTotalAtivos();
	}

	@Override
	public int buscarQuantidadeMarcasAtivos() {
		return marcaProdutoDAO.buscarQuantidadeTotalAtivos();
	}

	@Override
	public int buscarQuantidadeGruposAtivos() {
		return grupoProdutoDAO.buscarQuantidadeTotalAtivos();
	}

	@Override
	public List<Produto> buscarProdutosComEstoqueAbaixoLimiteMinino() {
		return produtoDAO.buscarProdutosComEstoqueAbaixoLimiteMinino(4);
	}
	
	@Override
	public List<Produto> buscarProdutosAtivosPorNome(String nome) {
		Produto produto = new Produto();
		produto.setAtivo(true);
		produto.setDescricao("%"+nome+"%");
		return produtoDAO.buscarPorExemplo(produto);
	}

	@Override
	public void setGrupoProdutoDAO(GrupoProdutoDAO grupoProdutoDAO) {
		this.grupoProdutoDAO = grupoProdutoDAO;
	}

	@Override
	public List<GrupoProduto> listarGruposProdutoAtivos() {
		GrupoProduto grupoProduto = new GrupoProduto();
		grupoProduto.setAtivo(true);
		return grupoProdutoDAO.buscarPorExemplo(grupoProduto);
	}

	@Override
	public List<MarcaProduto> listarMarcasProdutoAtivos() {
		MarcaProduto marcaProduto = new MarcaProduto();
		marcaProduto.setAtivo(true);
		return marcaProdutoDAO.buscarPorExemplo(marcaProduto);
	}

	@Override
	public void setProdutoDAO(ProdutoDAO produtoDAO) {
		this.produtoDAO = produtoDAO;
	}
}
